using System;
using System.Data;
using Oracle.ManagedDataAccess.Client;
using Oracle.ManagedDataAccess.Types;
using OracleInternal.Common;

namespace OracleInternal.BinXml
{
	internal class ObxmlMetaDataRepository : IDisposable
	{
		public void Dispose()
		{
		}

		internal ObxmlMetaDataRepository()
		{
		}

		internal bool Validate(ObxmlDecodeContext decodeContextForCurrentCall)
		{
			if (decodeContextForCurrentCall != null && decodeContextForCurrentCall.DbConnection != null)
			{
				return decodeContextForCurrentCall.TokenMap != null;
			}
			return false;
		}

		internal OracleXmlType GetTokenSet(ObxmlDecodeContext decodeContext, ulong tokenId, TokenTypes tokenType, string nameSpaceId, byte[] guid = null, bool bPopulateTokenMap = false)
		{
			if (ObxmlDecodeContext.m_XMLTypeOpcodeDump && ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)16777472, OracleTraceClassName.ObxmlMetaDataRepository, OracleTraceFuncName.GetTokenSet, "(BinXMLOpcodeDump) ***** +++++Fetching Token Set+++++ ******");
			}
			if (!Validate(decodeContext))
			{
				throw new OracleException(ResourceStringConstants.XML_TYPE_BINARY_INTERNAL_ERROR, string.Empty, string.Empty, ObxmlDecodeResponse.GetErrorMessage(ObxmlErrorTypes.MetaDataRepositoryInvalid));
			}
			try
			{
				OracleCommand oracleCommand = new OracleCommand("xdb.dbms_csx_int.GETVOCABULARYNOTXN", decodeContext.DbConnection);
				oracleCommand.CommandType = CommandType.StoredProcedure;
				oracleCommand.Parameters.Add("Result", OracleDbType.XmlType, 1);
				oracleCommand.Parameters["Result"].Direction = ParameterDirection.ReturnValue;
				oracleCommand.Parameters.Add("VOCABID", OracleDbType.Long).Value = tokenId;
				oracleCommand.Parameters.Add("VOCABTYPE", OracleDbType.Long).Value = ((tokenType != 0) ? 1 : 0);
				if (guid != null)
				{
					oracleCommand.Parameters.Add("RGUID", OracleDbType.Clob).Value = guid;
				}
				oracleCommand.ExecuteNonQuery();
				OracleXmlType oracleXmlType = (OracleXmlType)oracleCommand.Parameters["Result"].Value;
				if (bPopulateTokenMap)
				{
					PopulateTokenSet(decodeContext, oracleXmlType, tokenType == TokenTypes.NamespaceToken);
				}
				return oracleXmlType;
			}
			catch (Exception)
			{
				throw new OracleException(ResourceStringConstants.XML_TYPE_BINARY_INTERNAL_ERROR, string.Empty, string.Empty, ObxmlDecodeResponse.GetErrorMessage(ObxmlErrorTypes.TokenRetrievalFailed));
			}
		}

		internal string GetResource(ObxmlDecodeContext decodeContext, string absPath)
		{
			if (!Validate(decodeContext))
			{
				throw new OracleException(ResourceStringConstants.XML_TYPE_BINARY_INTERNAL_ERROR, string.Empty, string.Empty, ObxmlDecodeResponse.GetErrorMessage(ObxmlErrorTypes.MetaDataRepositoryInvalid));
			}
			string cmdText = "declare\n  res DBMS_XDBResource.XDBResource ;\nbegin\n  res := xdb.DBMS_XDB.getResource( abspath => :1 ) ;\n  :2 := DBMS_XDBResource.getContentVarchar2( res ) ;\nend ;\n";
			try
			{
				OracleParameter param = new OracleParameter("1", OracleDbType.Varchar2, absPath, ParameterDirection.Input);
				OracleParameter param2 = new OracleParameter("2", OracleDbType.Varchar2, ParameterDirection.Output);
				OracleCommand oracleCommand = new OracleCommand(cmdText, decodeContext.DbConnection);
				oracleCommand.CommandType = CommandType.Text;
				oracleCommand.BindByName = false;
				oracleCommand.Parameters.Add(param);
				oracleCommand.Parameters.Add(param2);
				oracleCommand.ExecuteNonQuery();
				return (string)oracleCommand.Parameters["2"].Value;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)285212672, OracleTraceClassName.ObxmlMetaDataRepository, OracleTraceFuncName.GetResource, ex);
				throw;
			}
		}

		internal void PopulateTokenSet(ObxmlDecodeContext decodeContext, OracleXmlType tokenSet, bool isNameSpaceTokenSet)
		{
			ObxmlDecoder obxmlDecoder = (ObxmlDecoder)decodeContext;
			obxmlDecoder.DecodeState.ProcessingTokenSet = true;
			if (!Validate(decodeContext))
			{
				throw new OracleException(ResourceStringConstants.XML_TYPE_BINARY_INTERNAL_ERROR, string.Empty, string.Empty, ObxmlDecodeResponse.GetErrorMessage(ObxmlErrorTypes.MetaDataRepositoryInvalid));
			}
			if (ObxmlDecodeContext.m_XMLTypeOpcodeDump && ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.BinXML, OracleTraceClassName.ObxmlMetaDataRepository, OracleTraceFuncName.PopulateTokenSet, "(BinXMLOpcodeDump) ***** +++++Processing Token Set+++++ ******");
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.BinXML, OracleTraceClassName.ObxmlMetaDataRepository, OracleTraceFuncName.PopulateTokenSet, isNameSpaceTokenSet ? "(BinXMLOpcodeDump) ++++++++++++++++++++++NameSpace++++++++++++++++++++++" : "(BinXMLOpcodeDump) ++++++++++++++++++++++Element/Attribute++++++++++++++++++++++");
			}
			_ = tokenSet.Value;
			obxmlDecoder.DecodeState.ProcessingTokenSet = false;
			if (ObxmlDecodeContext.m_XMLTypeOpcodeDump && ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, OracleTraceTag.BinXML, OracleTraceClassName.ObxmlMetaDataRepository, OracleTraceFuncName.PopulateTokenSet, "(BinXMLOpcodeDump) ***** -----Processing Token Set Over----- ******");
			}
		}
	}
}
